package com.taichuan.selfcheck.ui.fragment.base;

import android.content.Context;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.orhanobut.logger.Logger;
import com.taichuan.keysupport.ViewFocus;
import com.taichuan.mvp.base.MvpBaseInterface;
import com.taichuan.mvp.base.MvpBasePresenter;
import com.taichuan.mvp.fragment.BaseFragment;
import com.taichuan.mvp.fragment.BaseFragmentManager;
import com.taichuan.selfcheck.ui.activity.base.AppBaseActivity;
import com.taichuan.selfcheck.ui.fragment.MainFragment;
import java.util.Timer;
import java.util.TimerTask;
import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.disposables.Disposable;

/**
 * Created by CamelLuo on 2018/10/19.
 * 实现了MVP架构 的 Fragment 应用层抽象基类
 * 请在该类中实现与项目相关的公用方法、流程
 */
public abstract class AppBaseFragment<V extends MvpBaseInterface, P extends MvpBasePresenter<V>> extends BaseFragment<V, P> {
    private  final String TAG = this.getClass().getSimpleName();

    private static final boolean IS_DEBUG_AUTO_FINISH = true;
    private static final String AUTO_FINISH_TAG = "AutoFinish";

    protected ViewFocus mViewFocus = new ViewFocus();

    /**
     * 定义一个变量用于控制 页面自动超时结束的时间 默认为30秒
     */
    private static final int DEFAULT_AUTO_FINISH_PAGE_TIME = 30;

    /**
     * 定义一个变量用于进行页面自动超时倒计时计数
     */
    private int pageCountdownTime = 0;
    /**
     * 定义一个变量用于控制当前 页面自动超时定时器是否处于暂停状态
     */
    private boolean isPauseTimer = false;
    /**
     * 页面自动超时定时器
     */
    private Timer autoFinishTimer = null;
    /**
     * 页面自动超时定时器任务
     */
    private AutoFinishTimerTask autoFinishTimerTask = null;

    //管理RxJava，主要针对RxJava异步操作造成的内存泄漏
    private CompositeDisposable mCompositeDisposable;
    protected AppBaseActivity appBaseActivity;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        debugAutoFinishLog( "正在执行 onCreateView() 方法");
        //初始化并启动页面超时结束定时器
        if (isAllowAutoFinishFragment()) {
            debugAutoFinishLog(" 页面准备初始化 超时结束定时器");
            initAutoFinishTimer();
            startAutoFinishTimer();
        } else {
            debugAutoFinishLog(" 页面不执行页面超时结束定时器");
        }
        mCompositeDisposable = new CompositeDisposable();
        return super.onCreateView(inflater, container, savedInstanceState);
    }

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        appBaseActivity = (AppBaseActivity) context;
    }

    @Override
    public void onStart() {
        super.onStart();
        debugAutoFinishLog( "正在执行 onStart() 方法");
    }

    @Override
    public void onResume() {
        super.onResume();
        debugAutoFinishLog( "正在执行 onResume() 方法");
        //恢复页面超时结束定时器工作状态
        resumeAutoFinishTimer();
    }

    @Override
    public void onHiddenChanged(boolean hidden) {
        super.onHiddenChanged(hidden);
        debugAutoFinishLog( "正在执行 onHiddenChanged() 方法,此时是否隐藏Fragment：  " + hidden);
    }

    @Override
    public void onPause() {
        super.onPause();
        debugAutoFinishLog( "正在执行 onPause() 方法");
        //暂停页面超时结束定时器工作状态
        pauseAutoFinishTimer();
    }

    @Override
    public void onStop() {
        super.onStop();
        debugAutoFinishLog( "正在执行 onStop() 方法");
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        debugAutoFinishLog( "正在执行 onDestroy() 方法");
        //注销页面页面超时结束定时器
        destroyAutoFinishTimer();
        if (mCompositeDisposable != null) {
            mCompositeDisposable.clear();
        }
    }

    /**
     * 定义一个方法用于初始化页面超时自动结束定时器
     */
    protected void initAutoFinishTimer() {
        // 初始化计时器
        autoFinishTimer = new Timer();
        //初始化计时器任务
        autoFinishTimerTask = new AutoFinishTimerTask();
    }

    /**
     * 定义一个方法用于启动页面超时自动结束定时器
     */
    protected void startAutoFinishTimer() {
        // 初始化计时器
        if (autoFinishTimer == null) {
            autoFinishTimer = new Timer();
        }
        if (autoFinishTimerTask == null) {
            autoFinishTimerTask = new AutoFinishTimerTask();
        }

        if (autoFinishTimer != null) {
            autoFinishTimer.schedule(autoFinishTimerTask, 1000, 1000);
            debugAutoFinishLog(" 页面启动自动超时任务");
        }
    }

    /**
     * 定义一个方法用于暂停页面超时自动结束定时器
     */
    protected void pauseAutoFinishTimer() {
        if (isAllowAutoFinishFragment()){
            pageCountdownTime = 0;
            isPauseTimer = true;
            debugAutoFinishLog(" 页面进入暂停计时状态");
        }
    }

    /**
     * 定义一个方法用于恢复页面超时自动结束定时器
     */
    protected void resumeAutoFinishTimer() {
        if (isAllowAutoFinishFragment()){
            if (autoFinishTimer == null || autoFinishTimerTask == null) {
                startAutoFinishTimer();
            }

            pageCountdownTime = 0;
            isPauseTimer = false;
            debugAutoFinishLog(" 页面恢复计时状态");
        }
    }

    /**
     * 定义一个方法用于供外部组件调用 恢复还是暂停页面超时自动结束定时器
     *
     * @param isOpen
     */
    public void resumeOrPauseAutoFinishFragment(boolean isOpen) {
        if (isOpen) {
            resumeAutoFinishTimer();
        } else {
            pauseAutoFinishTimer();
        }
    }

    /**
     * 定义一个方法用于注销页面超时自动结束定时器
     */
    protected void destroyAutoFinishTimer() {
        if (isAllowAutoFinishFragment()){
            if (autoFinishTimer != null) {
                autoFinishTimer.cancel();
            }

            autoFinishTimer = null;
            autoFinishTimerTask = null;
            debugAutoFinishLog(" 页面注销自动超时任务");
        }
    }

    /**
     * 定义一个内部类用于实现页面自动超时功能
     */
    private class AutoFinishTimerTask extends TimerTask {
        @Override
        public void run() {
            if (isAllowAutoFinishFragment()){
                if (!isPauseTimer) {
                    //计时增加
                    pageCountdownTime++;
//                    debugAutoFinishLog(" 正在进行页面超时倒计时，当前秒数：  " + pageCountdownTime);
                    if (pageCountdownTime == getAutoFinishTime()) {
                        debugAutoFinishLog(" 页面超时,结束页面：  " + pageCountdownTime);
                        //关闭计时器
                        destroyAutoFinishTimer();
                        //交由子类完成是否需要在页面超时自动结束时执行相关逻辑
                        doOnAutoFinishFragment();
                        //不执行真实结束页面，是否结束交由子类实现（由于Fragment特殊性质，有可能是销毁，也有可能是切换，也有可能是在ViewPager中执行翻页）
                    }
                }
            }
        }
    }

    /**
     * 定义一个方法用于设置 页面超时自动结束的时间
     *
     * @return
     */
    protected int getAutoFinishTime() {
        return DEFAULT_AUTO_FINISH_PAGE_TIME;
    }

    public BaseFragmentManager getActivityBaseFragmentManager(){
        if (appBaseActivity != null){
            return appBaseActivity.getBaseFragmentManager();
        }else {
            return null;
        }
    }

    /**
     * 定义一个方法用于检测能否执行 FragmentManager 的操作
     * @return
     */
    public boolean checkCanOperateFragmentManager() {
        if (getActivityBaseFragmentManager() != null) {
            return true;
        } else {
            showMsg("操作频繁，请稍后再试！");
            return false;
        }
    }

    /**
     * 定义一个方法用于执行 FragmentManager 的 back() 操作
     */
    public void operateFragmentManagerBack(){
        if (checkCanOperateFragmentManager()){
            getActivityBaseFragmentManager().back();
        }
    }

    /**
     * 设置除了主页面，其他页面均为按 * 号键返回
     * @param event
     * @return
     */
    @Override
    public boolean dispatchKeyEvent(KeyEvent event) {
        if (event.getKeyCode()== KeyEvent.KEYCODE_STAR){
            if (!(getActivityBaseFragmentManager().getCurrentFragment() instanceof MainFragment)){
                doOnAutoFinishFragment();
            }
        }
        return super.dispatchKeyEvent(event);
    }

    /**
     * 定义一个方法用于debug打印调试自动超时相关log
     *
     * @param content
     */
    protected void debugAutoFinishLog(String content) {
        if (IS_DEBUG_AUTO_FINISH) {
            Logger.t(AUTO_FINISH_TAG).i(this.getClass().getSimpleName() + content);
        }
    }

    protected void addSubscribe(Disposable disposable) {
        if (mCompositeDisposable == null) {
            mCompositeDisposable = new CompositeDisposable();
        }
        mCompositeDisposable.add(disposable);
    }

    public <E extends View> E $$(int resId) {
        E e = this.findViewById(resId);
        mViewFocus.add(e);
        return e;
    }

    ////////////////////////////////////////////////////抽象方法相关/////////////////////////////////////////////////////////////////////

    /**
     * 定义一个抽象方法用于是否启动 页面超时自动结束定时器
     *
     * @return 是否允许启动，默认为false
     */
    protected abstract boolean isAllowAutoFinishFragment();

    /**
     * 定义一个抽象方法用于 在执行 页面超时自动结束 时 需要完成的事情
     *
     * @return 是否允许启动，默认为false
     */
    public abstract void doOnAutoFinishFragment();
}
